/*
 *  Copyright 2020, dqsjqian(Mr.Zhang).  All right reserved.
 *
 *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF dqsjqian(Mr.Zhang).
 *  LTD.  THE CONTENTS OF THIS FILE MAY NOT BE DISCLOSED TO THIRD
 *  PARTIES, COPIED OR DUPLICATED IN ANY FORM, IN WHOLE OR IN PART,
 *  WITHOUT THE PRIOR WRITTEN PERMISSION OF dqsjqian(Mr.Zhang).
 *
 *
 *  Edit History:
 *
 *    2020-01-12 - Created by dqsjqian(Mr.Zhang) dqsjqian@163.com
 *	Blog: https://blog.csdn.net/dqsjqian
 *	Gitee: https://gitee.com/dqsjqian
 */

#include <iostream>
using namespace std;

class Context;

class State
{
public:
    virtual void Handle(Context* pContext) = 0;
};

class ConcreteStateA : public State
{
public:
    virtual void Handle(Context* pContext)
    {
        cout << "I am concretestateA." << endl;
    }
};

class ConcreteStateB : public State
{
public:
    virtual void Handle(Context* pContext)
    {
        cout << "I am concretestateB." << endl;
    }
};

class Context
{
public:
    Context(State* pState) : m_pState(pState) {}

    void Request()
    {
        if (m_pState)
        {
            m_pState->Handle(this);
        }
    }

    void ChangeState(State* pState)
    {
        m_pState = pState;
    }

private:
    State* m_pState;
};

int main()
{
    State* pStateA = new ConcreteStateA();
    State* pStateB = new ConcreteStateB();
    Context* pContext = new Context(pStateA);
    pContext->Request();

    pContext->ChangeState(pStateB);
    pContext->Request();

    delete pContext;
    delete pStateB;
    delete pStateA;
}